﻿using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

namespace Microsoft.Win32
{
	internal static partial class NativeMethods
	{
		public class NativeResource : IDisposable
		{
			SafeLibraryHandle hLib;

			public NativeResource(string filename)
			{
				hLib = new SafeLibraryHandle(filename, LoadLibraryFlags.LOAD_LIBRARY_AS_DATAFILE | LoadLibraryFlags.LOAD_LIBRARY_AS_IMAGE_RESOURCE);
			}

			public void Dispose()
			{
				hLib = null;
			}

			public System.Drawing.Icon GetIcon(int id, System.Drawing.Size size)
			{
				IntPtr hIcon = LoadImage(hLib.DangerousGetHandle(), id, LoadImageType.ICON, size.Width, size.Height, LoadImageOptions.LOADTRANSPARENT);
				if (hIcon == IntPtr.Zero)
					throw new Win32Exception();
				System.Drawing.Icon ico = (System.Drawing.Icon)System.Drawing.Icon.FromHandle(hIcon).Clone();
				DestroyIcon(hIcon);
				return ico;
			}

			public string GetString(int id)
			{
				var sb = new System.Text.StringBuilder(260);
				int len = LoadString(hLib.DangerousGetHandle(), (uint)id, sb, 260);
				if (len == 0)
					return null;
				return sb.ToString();
			}

			public static string GetResourceString(string resourceReference)
			{
				string[] parts = resourceReference.Split(',');
				if (parts.Length != 2)
					throw new ArgumentException("Invalid string format.", nameof(resourceReference));
				int id;
				if (!int.TryParse(parts[1], out id))
					throw new ArgumentException("Invalid resource identifier.", nameof(resourceReference));
				string fn;
				try { fn = System.Environment.ExpandEnvironmentVariables(parts[0]); }
				catch (Exception ex) { throw new ArgumentException("Invalid file name part.", nameof(resourceReference), ex); }
				using (var nr = new NativeResource(fn))
					return nr.GetString(id);
			}
		}
	}
}